package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.service.IBedService;
import com.zzyl.nursing.service.ICheckInConfigService;
import com.zzyl.nursing.service.IElderService;
import com.zzyl.nursing.utils.ContractCodeGenerator;
import com.zzyl.nursing.utils.IdCardAgeCalculator;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.CheckInMapper;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;

/**
 * 入住Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-25
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ElderServiceImpl elderService;
    @Autowired
    private ContractServiceImpl contractService;
    @Autowired
    private BedServiceImpl bedService;
    @Autowired
    private ICheckInConfigService checkInConfigService;

    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    //开启事务
    @Transactional
    @Override
    public void apply(CheckInApplyDto dto) {
        try {
            //1.检查老人是否入住传入老人的id查询
            Elder elder = new Elder();
            BeanUtils.copyProperties(dto.getCheckInElderDto(), elder);
            //根据身份证号查询老人信息
            LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();

            queryWrapper.eq(Elder::getIdCardNo, elder.getIdCardNo()).eq(Elder::getStatus, 1);
            Elder one = elderService.getOne(queryWrapper);
            if (ObjectUtils.isNull(one)) {
                //2.更新床位状态为已入住
                Bed bed = updateBedStatus(dto);
                //3.新增或更新老人信息
                elder = updateOrInsertElderInfo(bed, dto);
                //4.新增签约办理
                insertContract(elder, dto);
                //5.新增入住信息
                insertCheckIn(elder, dto);

                //6.新增入住配置
                insertCheckInConfig(elder, dto);

            } else {
                //抛异常
                throw new BaseException("该老人已入住");
            }
        } catch (BeansException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 获取入住详细信息
     *
     * @param id
     */
    @Transactional
    @Override
    public CheckInDetailVo details(Long id) {
        try {
            //创建返回对象
            CheckInDetailVo vo = new CheckInDetailVo();
            //1.查询入住信息
            CheckIn checkIn = selectCheckInById(id);
            if (ObjectUtils.isNull(checkIn)) {
                throw new BaseException("入住信息不存在");
            }
            //2.查询老人信息
            Elder elder = elderService.selectElderById(checkIn.getElderId());
            CheckInElderVo checkInElderVo = new CheckInElderVo();
            BeanUtils.copyProperties(elder, checkInElderVo);
            //单独设置年龄
            int age = IdCardAgeCalculator.calculateAge(elder.getIdCardNo());
            checkInElderVo.setAge(age);
            //封装老人信息
            vo.setCheckInElderVo(checkInElderVo);
            //3.查询老人id查询合同
            LambdaQueryWrapper<Contract> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Contract::getElderId, elder.getId());
            Contract one = contractService.getOne(queryWrapper);
            //封装合同信息
            vo.setContract(one);

            //4.根据入住ID查询入住配置
            LambdaQueryWrapper<CheckInConfig> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(CheckInConfig::getCheckInId, checkIn.getId());
            CheckInConfig checkInConfig = checkInConfigService.getOne(queryWrapper1);
            //copy属性
            CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
            BeanUtils.copyProperties(checkInConfig, checkInConfigVo);
            checkInConfigVo.setStartDate(checkIn.getStartDate());
            checkInConfigVo.setEndDate(checkIn.getEndDate());
            checkInConfigVo.setBedNumber(checkIn.getBedNumber());
            //封装
            vo.setCheckInConfigVo(checkInConfigVo);


            //5.转换家属
            String remark = checkIn.getRemark();
            List<ElderFamilyVo> list = JSON.parseArray(remark, ElderFamilyVo.class);
            vo.setElderFamilyVoList(list);
            //6.封装数据返回前端

            return vo;
        } catch (BaseException e) {
            throw new RuntimeException(e);
        }
    }

    //2.更新床位状态方法
    private Bed updateBedStatus(CheckInApplyDto dto) {
        Bed bed = new Bed();
        bed.setBedStatus(1);
        bed.setId(dto.getCheckInConfigDto().getBedId());
        //修改床位信息
        bedService.updateById(bed);
        return bed;

    }

    //3.新增或更新老人信息方法
    private Elder updateOrInsertElderInfo(Bed bed, CheckInApplyDto dto) {
        //1.检查老人是否入住传入老人的id查询
        Elder elder = new Elder();
        BeanUtils.copyProperties(dto.getCheckInElderDto(), elder);
        //根据身份证号查询老人信息
        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Elder::getIdCardNo, elder.getIdCardNo()).eq(Elder::getStatus, 0);
        Elder one = elderService.getOne(queryWrapper);
        if (ObjectUtils.isNotNull(one)) {
            //更新老人信息
            elder.setBedId(bed.getId());
            elder.setStatus(1);
            elder.setId(one.getId());
            elderService.updateById(elder);

        } else {
            //新增老人信息
            elderService.insertElder(elder);

        }
        return elder;
    }

    //4.新增签约办理方法
    private void insertContract(Elder elder, CheckInApplyDto dto) {
        Contract contract = new Contract();
        contract.setElderId(elder.getId());
    /*    contract.setContractName(dto.getCheckInContractDto().getContractName());
        contract.setAgreementPath(dto.getCheckInContractDto().getAgreementPath());
        contract.setThirdPartyPhone(dto.getCheckInContractDto().getThirdPartyPhone());
        contract.setThirdPartyName(dto.getCheckInContractDto().getThirdPartyName());*/
        BeanUtils.copyProperties(dto.getCheckInContractDto(), contract);
        contract.setElderName(elder.getName());
        //设置合同编号
        contract.setContractNumber(ContractCodeGenerator.generate());
        //设置签约时间
        contract.setStartDate(dto.getCheckInConfigDto().getStartDate());
        //设置到期时间
        contract.setEndDate(dto.getCheckInConfigDto().getEndDate());
        // contract.setSignDate(dto.getCheckInContractDto().getSignDate());
        //设置状态  使用当前时间来做判断
        Integer status = contract.getStartDate().isBefore(LocalDateTime.now()) ? 1 : 0;
        contract.setStatus(status);
        contractService.insertContract(contract);


    }

    //新增入住信息方法
    private void insertCheckIn(Elder elder, CheckInApplyDto dto) {
        //创建checkIn对象
        CheckIn checkIn = new CheckIn();

        //根据床位id查询床位编号
        Bed bed = bedService.selectBedById(dto.getCheckInConfigDto().getBedId());
        checkIn.setBedNumber(bed.getBedNumber());
        //copy配置属性
        BeanUtils.copyProperties(dto.getCheckInConfigDto(), checkIn);
        checkIn.setElderId(elder.getId());
        checkIn.setElderName(elder.getName());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setStatus(0);
        //保存老人的家属列表
        String json = JSON.toJSONString(dto.getElderFamilyDtoList());
        checkIn.setRemark(json);
        //保存数据
        save(checkIn);
    }

    //6.新增入住配置方法
    private void insertCheckInConfig(Elder elder, CheckInApplyDto dto) {
        //创建checkIn对象
        CheckInConfig checkInConfig = new CheckInConfig();
        //copy配置属性
        BeanUtils.copyProperties(dto.getCheckInConfigDto(), checkInConfig);
        //根据老人ID查询入住ID
        LambdaQueryWrapper<CheckIn> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CheckIn::getElderId, elder.getId());
        CheckIn one = this.getOne(queryWrapper);
        checkInConfig.setCheckInId(one.getId());
        checkInConfigService.insertCheckInConfig(checkInConfig);
        //保存家属列表


    }
}
